
package com.trydofor.id.exec;

import java.util.Map;

import com.trydofor.aloe.exception.Exceptions;
import com.trydofor.id.doer.shell.ArgChecker;
import com.trydofor.id.doer.shell.Command;
import com.trydofor.id.doer.shell.Executer;
import com.trydofor.id.doer.shell.Outcome;
import com.trydofor.id.doer.shell.ShellDoer;
import com.trydofor.id.ware.WareFactory;

/**
 * @author : Shi Rongjiu (www.trydofor.com)
 */
public class ShellExe implements Executer {
    
    private final Command     registerCommand;
    private final Command     unregisterCommand;
    
    private final ShellDoer   shellDoer;
    private final WareFactory factory;
    
    /**
     * constructor
     * 
     * @param doer the shell
     * @param factory the ware context
     * @throws NullPointerException if doer or factory is null
     */
    public ShellExe(ShellDoer doer, WareFactory factory) {
        Exceptions.checkNullPointer(doer);
        Exceptions.checkNullPointer(factory);
        this.shellDoer = doer;
        this.factory = factory;
        this.registerCommand = ShellCmd.registerCommand();
        this.unregisterCommand = ShellCmd.unregisterCommand();
    }
    
    /**
     * {@inheritDoc}
     */
    public Outcome execute(Command command, Map<String, String> argdata) {
        
        String err = ArgChecker.check(command, argdata);
        if (err != null) return new Outcome(-1, null, err);
        
        if (registerCommand.getAlias().equals(command.getAlias())) {
            return registerCommand(command, argdata);
        }
        else if (unregisterCommand.getAlias().equals(command.getAlias())) {
            return unregisterCommand(command, argdata);
        }
        return new Outcome(-1, null, "Command is unsupported:" + command);
    }
    
    // ------------------
    private Outcome registerCommand(Command command, Map<String, String> argdata) {
        try {
            String name = argdata.get("name");
            String cmdn = argdata.get("comand");
            String exen = argdata.get("executer");
            Command cmd = (Command) factory.getInstance(cmdn);
            if (cmd == null) {
                return new Outcome(-2, "Command Not Found" + cmdn, null);
            }
            
            Executer exe = (Executer) factory.getInstance(exen);
            if (exe == null) {
                return new Outcome(-2, "Executer Not Found" + exen, null);
            }
            
            shellDoer.register(name, cmd, exe);
            return new Outcome(0, "register command:" + name, null);
        }
        catch (Exception e) {
            return new Outcome(-1, null, Exceptions.printStackTrace(e));
        }
        
    }
    
    private Outcome unregisterCommand(Command command, Map<String, String> argdata) {
        try {
            String name = argdata.get("name");
            shellDoer.unregister(name);
            return new Outcome(0, "unregister command:" + name, null);
        }
        catch (Exception e) {
            return new Outcome(-1, null, Exceptions.printStackTrace(e));
        }
    }
}
